﻿using System;
using System.Collections.Generic;

namespace Net
{
    // A simple Event System that can be used for remote systems communication
    public static class MessageDispatcher
    {
        static readonly Dictionary<Type, Action<BaseMessage>> s_MessageHandles = new ();

        static readonly Dictionary<Delegate, Action<BaseMessage>> s_HandlerLookups = new ();   

        public static void RegisterMessageHandler<T>(Action<T> evt) where T : BaseMessage
        {
            if (!s_HandlerLookups.ContainsKey(evt))
            {
                Action<BaseMessage> newAction = (e) => evt((T)e);
                //void newAction(BaseMessage e) => evt((T) e);
                s_HandlerLookups[evt] = newAction;

                if (s_MessageHandles.TryGetValue(typeof(T), out Action<BaseMessage> internalAction))
                    s_MessageHandles[typeof(T)] = internalAction += newAction;
                else
                    s_MessageHandles[typeof(T)] = newAction;
            }
        }

        public static void UnregisterMessageHandler<T>(Action<T> evt) where T : BaseMessage
        {
            if (s_HandlerLookups.TryGetValue(evt, out var action))
            {
                if (s_MessageHandles.TryGetValue(typeof(T), out var tempAction))
                {
                    tempAction -= action;
                    if (tempAction == null)
                        s_MessageHandles.Remove(typeof(T));
                    else
                        s_MessageHandles[typeof(T)] = tempAction;
                }

                s_HandlerLookups.Remove(evt);
            }
        }

        public static void Dispatch(BaseMessage evt)
        {
            if (s_MessageHandles.TryGetValue(evt.GetType(), out var action))
                action.Invoke(evt);
        }

        public static void Clear()
        {
            s_MessageHandles.Clear();
            s_HandlerLookups.Clear();
        }
    }
}